1 O que são Modelos Multimodais?
Modelos que entendem múltiplos tipos de dados — não apenas texto.
As modalidades
Texto
A modalidade original dos LLMs. Entrada e saída de texto.
Imagem
Fotos, diagramas, gráficos, documentos escaneados, telas.
Áudio
Voz, música, sons ambientais. Speech-to-text e text-to-speech.
Vídeo
Sequências de frames com áudio. Análise temporal.
Modelos multimodais populares em 2026
| Modelo | Entrada | Saída | Destaque |
|---|---|---|---|
| GPT-4o | Texto + Imagem + Áudio | Texto + Imagem + Áudio | Nativo multimodal, baixa latência |
| Claude 3.5 Sonnet | Texto + Imagem | Texto | Visão de alta qualidade, 200K context |
| Gemini 1.5 Pro | Texto + Imagem + Áudio + Vídeo | Texto | 1M tokens de contexto, vídeo nativo |
| LLaVA | Texto + Imagem | Texto | Open-source, roda local |
| Qwen2-VL | Texto + Imagem + Vídeo | Texto | Open-source, multilíngue |
2 Como imagens viram tokens
Vision Transformers (ViT): dividindo imagens em "palavras visuais".
🎮 Simulador: Image → Patches → Tokens
Veja como uma imagem é dividida em patches
Tokens totais: 0 (patches + [CLS] token)
Interpretação: cada quadrado colorido é um patch que vira um token. Quanto menor o patch, mais tokens (mais detalhe, mais custo). O token [CLS] no início representa a imagem inteira.
O pipeline Vision Transformer
# Pipeline simplificado de um Vision Transformer # 1. Imagem de entrada: 224x224 pixels, 3 canais (RGB) image = load_image("nota_fiscal.jpg") # shape: (224, 224, 3) # 2. Divide em patches de 16x16 patches = image.reshape(14, 16, 14, 16, 3) # 14x14 = 196 patches patches = patches.reshape(196, 16*16*3) # cada patch: 768 números # 3. Projeção linear: cada patch vira um vetor de 768 dimensões patch_embeddings = Linear(768, 768)(patches) # 4. Adiciona [CLS] token (representa a imagem inteira) cls_token = Parameter(randn(1, 768)) embeddings = concat([cls_token, patch_embeddings]) # 197 tokens # 5. Adiciona positional encoding (ordem dos patches importa) embeddings = embeddings + positional_encoding # 6. Passa pelo Transformer (self-attention entre patches) features = TransformerEncoder(embeddings) # 7. Combina com texto (se for modelo multimodal) text_tokens = tokenize("Qual o valor total?") combined = concat([features, text_tokens]) output = TransformerDecoder(combined) # 8. Gera resposta answer = decode(output) # → "O valor total da nota fiscal é R$ 48.500,00"
Por que patches e não pixels individuais?
❌ Pixel por pixel
Imagem 224x224 = 50.176 tokens
Inviável computacionalmente.
Muito custo, pouco ganho.
✅ Patches 16x16
Imagem 224x224 = 196 tokens
Cada patch captura um "conceito visual".
Equilíbrio ideal entre detalhe e eficiência.
3 OCR inteligente com LLMs
Esqueça o OCR clássico — LLMs multimodais leem documentos diretamente.
🎮 Comparação: OCR clássico vs LLM multimodal
Veja como cada abordagem extrai informação de uma nota fiscal escaneada.
❌ Erros em O/0, S/5, valores numéricos. Sem compreensão do layout.
✅ Sem erros, entende contexto, layout e informações implícitas.
Exemplo: extraindo dados de NF com Claude 3
import anthropic import base64 client = anthropic.Anthropic() # Carrega imagem da NF with open("nf_12345.jpg", "rb") as f: image_data = base64.standard_b64encode(f.read()).decode("utf-8") # Chama Claude 3 com imagem response = client.messages.create( model="claude-3-5-sonnet-20251022", max_tokens=1024, messages=[{ "role": "user", "content": [ { "type": "image", "source": { "type": "base64", "media_type": "image/jpeg", "data": image_data } }, { "type": "text", "text": """Extraia os seguintes dados desta nota fiscal em JSON: - numero_nf - fornecedor - cnpj - data_emissao - valor_total - itens (lista com descrição e quantidade) Responda APENAS com o JSON, sem explicação.""" } ] }] ) # Resultado print(response.content[0].text) # { # "numero_nf": "12345", # "fornecedor": "Tech Ltda", # "cnpj": "00.000/0001-00", # "data_emissao": "2025-06-03", # "valor_total": 48500.00, # "itens": [ # {"descricao": "Switch gerenciável", "quantidade": 4}, # {"descricao": "Access point Wi-Fi 6", "quantidade": 8} # ] # }
Quando usar cada abordagem
| Situação | Recomendação | Por quê? |
|---|---|---|
| Texto limpo, digitado, alto volume | 🔤 OCR clássico (Tesseract) | Rápido, barato, bom o suficiente |
| Tabelas complexas, layouts mistos | 🧠 LLM multimodal | Entende estrutura, não só texto |
| Manuscritos, formulários | 🧠 LLM multimodal | OCR clássico falha muito |
| Precisa responder perguntas sobre o doc | 🧠 LLM multimodal | OCR só extrai texto, não responde |
| 10.000 documentos/dia, orçamento limitado | 🔤 OCR + LLM só nos casos difíceis | Híbrido: OCR barato + LLM quando necessário |
4 Attention em imagens — o que o modelo "olha"
Visualizando quais regiões da imagem o modelo considera importantes.
🎮 Simulador: Heatmap de atenção
Passe o mouse sobre as células para ver o peso de atenção. Cores mais quentes = mais atenção.
Pergunta: "Qual o valor total da nota fiscal?"
Interpretação: O modelo foca no campo onde está o valor, ignorando cabeçalhos e rodapés.
Por que isso importa?
Debug de erros
Se o modelo errou, o heatmap mostra onde ele "olhou". Talvez tenha focado no lugar errado.
Confiança
Ver o modelo focando no campo certo aumenta confiança na resposta.
Otimização
Se o modelo sempre ignora uma região, talvez possamos cortar essa parte da imagem.
5 Áudio e Fala
Speech-to-text, text-to-speech e modelos de voz nativos.
As 3 tarefas principais
Speech-to-Text (STT)
Transcrever áudio em texto. Ex: Whisper, Google Speech-to-Text.
Text-to-Speech (TTS)
Gerar fala a partir de texto. Ex: ElevenLabs, OpenAI TTS.
Voz nativa em LLMs
GPT-4o conversando em tempo real, entendendo tom e emoção.
Whisper — o padrão open-source
import whisper # Carrega modelo (tiny, base, small, medium, large) model = whisper.load_model("medium") # bom equilíbrio # Transcreve áudio result = model.transcribe("reuniao_2025-06-20.mp3") print(result["text"]) # "Bom dia, equipe. Vamos discutir os tickets de suporte da última semana..." # Com timestamps for segment in result["segments"]: print(f"[{segment['start']:.1f}s - {segment['end']:.1f}s] {segment['text']}") # [0.0s - 4.5s] Bom dia, equipe. # [4.5s - 9.2s] Vamos discutir os tickets de suporte...
Casos de uso na Nimbus Cloud
| Caso de uso | Modalidade | Ferramenta |
|---|---|---|
| Transcrever reuniões de equipe | 🎙️ Áudio → Texto | Whisper |
| Atendimento por voz | 🎤 Voz nativa | GPT-4o voice |
| Narrar respostas do RAG | 🔊 Texto → Áudio | ElevenLabs |
| Indexar podcasts internos | 🎙️ Áudio → Texto → RAG | Whisper + ChromaDB |
6 RAG Multimodal
Indexar não só texto, mas imagens, tabelas e diagramas.
Abordagens de RAG multimodal
Imagens como tokens
Envia a imagem direto ao LLM multimodal. Simples, mas caro em tokens.
Imagem → Texto → RAG
Usa LLM para descrever a imagem em texto, indexa o texto. Mais barato.
Embeddings multimodais
Modelos como CLIP geram vetores de imagem e texto no mesmo espaço.
Exemplo: RAG com imagens de NFs
from PIL import Image import chromadb import ollama # 1. Extrai descrição textual da imagem com LLM multimodal def describe_image(image_path): with open(image_path, "rb") as f: image_data = f.read() response = ollama.chat( model="llava:13b", # LLM multimodal local messages=[{ "role": "user", "content": "Descreva em detalhes o conteúdo deste documento. Inclua todos os números, datas, valores e nomes mencionados.", "images": [image_data] }] ) return response["message"]["content"] # 2. Indexa a descrição no Vector DB db = chromadb.Client() collection = db.get_or_create_collection("nimbus_multimodal") for nf_image in list_nf_images(): description = describe_image(nf_image) embedding = ollama.embed( model="nomic-embed-text", input=description ) collection.add( ids=[nf_image], embeddings=[embedding["embeddings"][0]], documents=[description], metadatas=[{"type": "nota_fiscal", "image_path": nf_image}] ) # 3. Consulta multimodal question = "Quais notas fiscais de equipamentos de rede chegaram em junho?" results = collection.query( query_embeddings=[ollama.embed("nomic-embed-text", question)["embeddings"][0]], n_results=3 ) # 4. Retorna imagens + descrições for result in results["metadatas"][0]: print(f"Imagem: {result['image_path']}") print(f"Descrição: {result['document']}")
CLIP — embeddings multimodais unificados
import clip import torch from PIL import Image # Carrega modelo CLIP (OpenAI) model, preprocess = clip.load("ViT-B/32") # Imagem e texto no MESMO espaço vetorial! image = preprocess(Image.open("nf_12345.jpg")).unsqueeze(0) text = clip.tokenize(["nota fiscal de equipamentos de rede"]) with torch.no_grad(): image_features = model.encode_image(image) text_features = model.encode_text(text) # Similaridade direta entre imagem e texto! similarity = torch.nn.functional.cosine_similarity( image_features, text_features ) print(f"Similaridade: {similarity.item():.3f}") # 0.28 # Busca: "quais imagens são sobre notas fiscais?" # CLIP compara o texto com todas as imagens diretamente!
7 Ferramentas e APIs práticas
Como usar modelos multimodais no dia a dia.
APIs comerciais
| API | Modalidades | Preço | Uso ideal |
|---|---|---|---|
| OpenAI GPT-4o | Texto + Imagem + Áudio | $$$ | Máxima qualidade, voz nativa |
| Anthropic Claude 3.5 | Texto + Imagem | $$ | Visão de alta qualidade, documentos |
| Google Gemini 1.5 | Texto + Imagem + Áudio + Vídeo | $$ | Vídeo longo, 1M tokens |
| ElevenLabs | Texto → Áudio | $$ | Voz ultra-realista |
Modelos locais (open-source)
| Modelo | Modalidades | Tamanho | Como rodar |
|---|---|---|---|
| LLaVA 13B | Texto + Imagem | ~8 GB | Ollama: ollama run llava:13b |
| Qwen2-VL 7B | Texto + Imagem + Vídeo | ~5 GB | Ollama: ollama run qwen2-vl |
| Whisper Medium | Áudio → Texto | ~1.5 GB | Python: whisper.load_model("medium") |
| Piper TTS | Texto → Áudio | ~75 MB | Local, rápido, várias vozes |
Exemplo completo: assistente multimodal local
import ollama import whisper from PIL import Image # 1. Transcreve áudio de pergunta whisper_model = whisper.load_model("medium") audio_result = whisper_model.transcribe("pergunta.mp3") question = audio_result["text"] print(f"Pergunta: {question}") # 2. Carrega imagem relevante image = Image.open("documento.jpg") # 3. Chama LLM multimodal com imagem + pergunta with open("documento.jpg", "rb") as f: image_data = f.read() response = ollama.chat( model="llava:13b", messages=[{ "role": "user", "content": question, "images": [image_data] }] ) answer = response["message"]["content"] print(f"Resposta: {answer}") # 4. Opcional: narra a resposta em áudio # (usando Piper TTS ou similar)
8 Conexão com RAG e próximos passos
Como multimodal expande o RAG — e o que vem depois.
Evolução do RAG
| Estágio | Capacidade | Exemplo |
|---|---|---|
| RAG básico | Busca em texto | Chunks de PDFs textuais |
| RAG com OCR | Busca em documentos escaneados | Tesseract + Vector DB |
| RAG multimodal | Busca em imagens, tabelas, diagramas | CLIP embeddings + Vector DB |
| RAG + Agent | Decide quando e como buscar | Agentic RAG com múltiplas ferramentas |
Casos de uso na Nimbus Cloud
Indexar NFs escaneadas
LLM multimodal extrai dados, Vector DB indexa. Busca por "NF de junho" encontra a imagem.
Buscar em tabelas
Diagramas e tabelas de relatórios técnicos indexados como imagens + descrição textual.
Transcrever reuniões
Whisper transcreve, Vector DB indexa. Busca por "decisão sobre timeout" acha o trecho.
Diagramas técnicos
Arquiteturas de rede, fluxogramas — buscáveis por descrição semântica.
Desafios do RAG multimodal
Custo de tokens
Imagens consomem muitos tokens. Para alto volume, use OCR + LLM híbrido.
Latência
Processar imagens é mais lento que texto. Cache resultados quando possível.
Precisão
LLMs multimodais podem "alucinar" detalhes visuais. Valide com OCR quando crítico.
Privacidade
APIs comerciais enviam imagens para a nuvem. Use modelos locais para dados sensíveis.
🎯 Quiz — teste seu conhecimento
Clique em uma alternativa para ver se acertou.
→ O que vem a seguir?
Agora que você entende modelos multimodais, vamos aprender a adaptá-los ao seu domínio.
Conceitos que vamos construir aqui
Quando fine-tuning
RAG vs Fine-tuning: quando usar cada um.
LoRA / QLoRA
Fine-tuning eficiente: ajusta só 1% dos parâmetros.
Datasets
Como preparar dados de treinamento de qualidade.
Avaliação
Métricas para saber se o fine-tuning funcionou.